package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.constant.ComponentTypeConstants;
import com.bsg.upm.constant.MonitorCommonMap;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

@Service
public class MonitorComponentService extends BaseService {

	public RespJson getAllComponent(String stieId) throws APIException {
		try {

			JSONArray ret = getAllComponentFromHS(stieId);
			return RespJsonFactory.buildOK(ret);
		} catch (Exception e) {
			logger.error("getAllComponent fail:", e);
			throw new APIException("getAllComponent fail:" + e.getMessage());
		}
	}
	
 
	public RespJson getAllHostComponent(String siteId,String clusterId) throws APIException {
		try {
			JSONArray ret = new JSONArray();


			Map<String, Object> paramMap = new HashMap<String, Object>();
			
			paramMap.put("clusterId", clusterId);
			paramMap.put("siteId", siteId);
			List<HostEntity> hostEntities = hostDao.list(paramMap);
			if (hostEntities == null || hostEntities.isEmpty()) {
				return RespJsonFactory.buildOK(ret);
			}

			if (siteId==null) {
				siteId = hostEntities.get(0).getCluster().getArea().getSite().getId();
			}
			
			JSONArray mghosts = getHostInfoFromMG(siteId);
			JSONObject plugins= getHostComponentStatusFromHS(siteId, ComponentTypeConstants.DOCERK_PLUGIN_STATUS);
			JSONObject swarmagents= getHostComponentStatusFromHS(siteId, ComponentTypeConstants.SWARM_AGENT_STATUS);
			JSONObject dockers= getHostComponentStatusFromHS(siteId, ComponentTypeConstants.DOCKER_STATUS);
			
			for (HostEntity hostEntity : hostEntities) {
				String hostStatus = getHostStatus(hostEntity.getRelateId(), mghosts);
				JSONObject object = getShowHostObj(plugins,swarmagents,dockers, hostEntity,hostStatus );
				ret.add(object);

			}

			return RespJsonFactory.buildOK(ret);
		} catch (Exception e) {
			logger.error("getAllHostComponent fail:", e);
			throw new APIException("getAllHostComponent fail:" + e.getMessage());
		}
	}

	public RespJson getAllHostContainersStatus(String hostId) throws APIException {
		try {
			JSONArray ret = new JSONArray();

			HostEntity hostEntity = hostDao.get(hostId);
			if (hostEntity == null) {
				return RespJsonFactory.buildOK(ret);
			}

			String siteId = hostEntity.getCluster().getArea().getSite().getId();

			JSONArray containers = getContanerInfoFromMG(siteId, hostEntity.getRelateId());

			for (Object tmp : containers) {
				JSONObject container = (JSONObject) tmp;

				JSONObject object = new JSONObject();
				object.put("container_name", container.getString("name"));
				object.put("unit_type", container.getJSONObject("labels").getString("mgm.unit.type"));
				
				object.put("container_status", container.getString("state"));

				ret.add(object);
			}

			return RespJsonFactory.buildOK(ret);

		} catch (Exception e) {
			logger.error("getAllHostContainersStatus fail:", e);
			throw new APIException("getAllHostContainersStatus fail:" + e.getMessage());
		}
	}

	private JSONArray getContanerInfoFromMG(String siteId, String mgmHostId) throws APIException {
		String urlPattern = "/{0}/hosts/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.MGM_VERSION, mgmHostId);
		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_MGM, url);

		if (httpRespJson.getStatus() == HttpStatus.SC_OK) {
			JSONObject ret = ((JSONObject) httpRespJson.getData());

			if (ret.isEmpty()) {
				return new JSONArray();
			}

			return ret.getJSONArray("containers");
		} else {
			throw new APIException(httpRespJson.getMsg());
		}
	}

	private JSONObject getShowHostObj(JSONObject plugins,JSONObject swarmAgents,JSONObject dockers, HostEntity hostEntity, String hostStatus ) {
		JSONObject object = new JSONObject();

		object.put("cluster_name",hostEntity.getCluster().getName());
		object.put("cluster_id",hostEntity.getCluster().getId());
		
		object.put("host_name", hostEntity.getName());
		object.put("host_id", hostEntity.getId());
		object.put("host_status", hostStatus);

		object.put(ComponentTypeConstants.DOCERK_PLUGIN_STATUS,
				getComponentStatus(ComponentTypeConstants.DOCERK_PLUGIN_STATUS, plugins,hostEntity.getRelateId()));

		object.put(ComponentTypeConstants.DOCKER_STATUS,
				getComponentStatus(ComponentTypeConstants.DOCKER_STATUS, dockers,hostEntity.getRelateId()));

		object.put(ComponentTypeConstants.SWARM_AGENT_STATUS,
				getComponentStatus(ComponentTypeConstants.SWARM_AGENT_STATUS, swarmAgents,hostEntity.getRelateId()));


		return object;
	}

	private String getHostStatus(String hostRelateId, JSONArray mghosts) {
		if (hostRelateId==null){
			return ComponentTypeConstants.STATUS_UNKNOWN;
		}
		
		for (Object tmp : mghosts) {
			JSONObject host = (JSONObject) tmp;

			if (hostRelateId.equals(host.getString("id"))) {

				if (host.getBoolean("enabled")) {
					return ComponentTypeConstants.STATUS_PASSING;
				} else {
					return ComponentTypeConstants.STATUS_CRITICAL;
				}
			}
		}

		return ComponentTypeConstants.STATUS_UNKNOWN;
	}

	private String getComponentStatus(String componentType, JSONObject components,String hostRelateId) {
		if (hostRelateId==null || !components.containsKey(hostRelateId) ){
			return ComponentTypeConstants.STATUS_UNKNOWN;
		}
	 
		JSONObject metric =getNoHistoryFromcommonType(components.getJSONObject(hostRelateId));
		if (metric==null || metric.isEmpty() ){
			return ComponentTypeConstants.STATUS_UNKNOWN;
		}
		 
		return metric.getString("value");
	}

	private JSONArray getHostInfoFromMG(String siteId) throws APIException {
 
		String url = String.format("/%s/hosts", SysConstants.MGM_VERSION);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_MGM, url);

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("getHostInfoFromMG  fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return (JSONArray) httpRespJson.getData();

	}

	
	//系统组件
	private JSONArray getAllComponentFromHS(String stieId) throws APIException {
		String url = String.format("/%s/component/all", SysConstants.HS_VERSION);
		RespJson httpRespJson = sendHttpGet(stieId, SysConstants.INTERFACE_TYPE_HS, url);

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("getAllComponentFromHS:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		JSONObject ret = (JSONObject) httpRespJson.getData();

		if (ret.isEmpty()) {
			return new JSONArray();
		}

		return ret.getJSONArray("Component");
	}

 

	private JSONObject getHostComponentStatusFromHS(String siteId, String componentType) throws APIException {
		try {
			String metric = definitionMetricCache.getMetric(MonitorCommonMap.HOST_TYPE, componentType);
			long end = System.currentTimeMillis() / 1000;
			long start = end - 60 * 3;

			String url = String.format("/%s/hosts?start_time=%d&end_time=%d&metric=%s", SysConstants.HS_VERSION,
					start, end, metric);

			RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

			if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
				logger.error("get horus fail:" + httpRespJson);
				throw new APIException(httpRespJson.getMsg());
			}

	 	
			return (JSONObject) httpRespJson.getData();
		} catch (Exception e) {
			logger.error("getHostComponentStatusFromHS fail:", e);
			throw new APIException("getHostComponentStatusFromHS fail:" + e.getMessage());
		}

	}
}
